#include <cassert>
#include "GL/glfw.h"
#include "glm/glm.hpp"

#ifndef SPRITE_HEADER
#define SPRITE_HEADER

//origin is lower left
struct Texture {
	Texture ()
		: 
	mTexName(-1)
	{}

	//XXX Perhaps use DevIL later on to support other formats
	int LoadFromImageTGA( const char * name ) {
		mTexName = -1;
		if ( glfwReadImage( name, &mImage, 0) ) {
			//Generate the name
			glGenTextures(1, &mTexName);

			//XXX Make this an exception area
			assert (mTexName != -1);

			glBindTexture(GL_TEXTURE_2D, mTexName);

			glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
				 GL_LINEAR );
			glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
				 GL_LINEAR );

			glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, 
				GL_REPEAT );
			glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, 
				GL_REPEAT );

			glfwLoadTextureImage2D( &mImage, 0 );

			glBindTexture(GL_TEXTURE_2D, 0);
		}

		return mTexName;
	}

	bool IsLoaded() { return (mTexName != -1); }

	glm::ivec2 GetWH() { return glm::ivec2( mImage.Width, mImage.Height ); }

	int GetFormat() { return mImage.Format ; }

	int GetBytesPerPixel(){ return mImage.BytesPerPixel ; }
	
	void BindWithGL();//Binds the texture to the current texture unit.

	GLuint mTexName; //OpenGL generated name.

	GLFWimage mImage;
};

//A single sprite
class Sprite {
public:

	Sprite () 
	{
		mUV = glm::vec2(0.0, 0.0);
		mUVWH = glm::vec2(1.0, 1.0);
		mTexture = NULL;
	}


	const glm::vec2 & GetUV() {
		return this->mUV;
	}

	void SetUV( const glm::vec2 & inUV) {
		mUV = inUV;
	}

	const glm::vec2 & GetUVWH() {
		return this->mUVWH;
	}
	
	void SetUVWH( const glm::vec2 & inUVWH) {
		mUVWH = inUVWH;
	}

	const glm::vec2 & GetPos() {
		return this->mPos;
	}

	void SetPos( const glm::vec2 & inPos) {
		mPos = inPos;
	}
	
	Texture * GetTexture() { return mTexture; }
	
	void SetTexture(Texture * inTex ) {
		mTexture = inTex;
	}
	/*
	void Update( float timeStep ) {
		if (IsOutOfCycles() ) {
			mFinished = true;
			return;
		}

		mCurrFrameTime += timeStep;

		if (mCurrFrameTime > mFrameDuration && mFrameDuration != -1 ){
			float diff = mCurrFrameTime - mFrameDuration;
			mCurrFrameTime = diff;

			IncrementCurrentFrame();
		}

	}
	*/
private:
	Texture * mTexture;
	
	glm::vec2 mUV; //Current U,V pos of left corner of sprite.
	glm::vec2 mUVWH; //Width and height of sprite in U,V coordinates.

	glm::vec2 mPos; //the current position

};

#endif